/*
 * Copyright 2008 Jens Meiss
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package hmvc.j2me.framework.component;

import hmcv.j2me.component.Component;
import hmvc.component.IComponent;
import hmvc.j2me.framework.controller.IHmvcController;
import hmvc.j2me.framework.events.IHmvcEvent;
import hmvc.j2me.framework.events.IHmvcEventListener;
import hmvc.j2me.framework.events.TerminateEvent;
import hmvc.j2me.framework.model.IHmvcModel;
import hmvc.j2me.framework.view.IHmvcView;

/**
 * This is the basic IHmvcComponent-Implementation. Extend this Class to create
 * you own Component-Implementations.
 * 
 * @author jens.meiss
 */
public class HmvcComponent implements IHmvcComponent {

	private static Component getInstance(IHmvcController controller,
			IHmvcModel model, IHmvcView view) {

		if ((controller != null) && (model != null) && (view != null)) {
			return new Component(controller.getController(), model.getModel(),
					view.getView());
		} else if ((controller != null) && (model != null) && (view == null)) {
			return new Component(controller.getController(), model.getModel());
		} else if ((controller != null) && (model == null) && (view != null)) {
			return new Component(controller.getController(), view.getView());
		} else if ((controller != null) && (model == null) && (view == null)) {
			return new Component(controller.getController());
		} else {
			// TODO loggin, throw exception?
			return null;
		}
	}

	private Component component;

	private IHmvcModel model;

	private IHmvcView view;

	private IHmvcController hmvcController;

	public HmvcComponent(IHmvcController controller) {
		createComponent(controller, null, null);
	}

	public HmvcComponent(IHmvcController controller, IHmvcModel model) {
		createComponent(controller, model, null);
	}

	public HmvcComponent(IHmvcController controller, IHmvcModel model,
			IHmvcView view) {
		createComponent(controller, model, view);
	}

	public HmvcComponent(IHmvcController controller, IHmvcView view) {

		createComponent(controller, null, view);
	}

	public IHmvcComponent addChildComponent(IHmvcController controller) {

		IHmvcComponent childComponent = new HmvcComponent(controller);

		childComponent.getComponent().setParentComponent(this.component);

		this.component.addChildComponent(childComponent.getComponent());

		return childComponent;
	}

	public IHmvcComponent addChildComponent(IHmvcController controller,
			IHmvcModel model) {

		IHmvcComponent childComponent = new HmvcComponent(controller, model);

		childComponent.getComponent().setParentComponent(this.component);

		this.component.addChildComponent(childComponent.getComponent());
		return childComponent;
	}

	public IHmvcComponent addChildComponent(IHmvcController controller,
			IHmvcModel model, IHmvcView view) {
		IHmvcComponent childComponent = new HmvcComponent(controller, model,
				view);

		childComponent.getComponent().setParentComponent(this.component);

		this.component.addChildComponent(childComponent.getComponent());
		return childComponent;
	}

	public IHmvcComponent addChildComponent(IHmvcController controller,
			IHmvcView view) {
		IHmvcComponent childComponent = new HmvcComponent(controller, view);

		childComponent.getComponent().setParentComponent(this.component);

		this.component.addChildComponent(childComponent.getComponent());
		return childComponent;
	}

	private void createComponent(IHmvcController controller, IHmvcModel model,
			IHmvcView view) {
		
		controller.setComponent(this);
		
		if (model != null) {
			model.setHmvcController(controller);
		}
		
		if (view != null) {
			view.setHmvcController(controller);
		}
		

		setHmvcController(controller);
		setHmvcModel(model);
		setHmvcView(view);

		this.component = getInstance(controller, model, view);
		this.component.initComponentParts();
	}

	public void fireEvent(IHmvcEvent event, boolean up, boolean local,
			boolean down) {

		if (event instanceof TerminateEvent) {
			component.terminate();
			return;
		}

		component.fireEvent(event, up, local, down);
	}

	public IComponent getComponent() {
		return component;
	}

	public IHmvcController getHmvcController() {
		return hmvcController;
	}

	public IHmvcModel getHmvcModel() {
		return model;
	}

	public IHmvcView getHmvcView() {
		return view;
	}

	public void register(Class classOfEvent, IHmvcEventListener listener) {
		this.component.register(classOfEvent, listener.getEventListener());
	}

	public void setHmvcController(IHmvcController hmvcController) {
		this.hmvcController = hmvcController;
	}

	public void setHmvcModel(IHmvcModel model) {
		this.model = model;
	}

	public void setHmvcView(IHmvcView view) {
		this.view = view;
	}

}
